using System.Linq;
using System.Windows.Forms;
using CodePlex.DnD4eCampaignManager.DnD4e;
using CodePlex.DnD4eCampaignManager.Presentation.ViewInterfaces;
using CodePlex.DnD4eCampaignManager.Repositories;
using CodePlex.DnD4eCampaignManager.Services.Interfaces;

namespace CodePlex.DnD4eCampaignManager.Presentation
{
    public class CampaignManagerPresenter
    {
        private const string CAMPAIGN_PLANS_PREFIX = "CampaignPlans";
        private const string COMBAT_TRACKER_PREFIX = "CombatTracker";
        private const string IMPORT_MONSTER = "ImportMonster";
        private const string IMPORT_PLAYER_CHARACTER = "ImportPlayerCharacter";
        private const string LOCATION_TAB_PREFIX = "Location_";
        private const string MONSTER_TAB_PREFIX = "Monster_";
        private const string NEW_LOCATION_PREFIX = "NewLocation";
        private const string NEW_MONSTER_PREFIX = "NewMonster";
        private const string PLAYER_CHARACTER_TAB_PREFIX = "PlayerCharacter_";
        private readonly IDungeonsAndDragonsInsiderMonsterImporter _dungeonsAndDragonsInsiderMonsterImporter;
        private readonly IDungeonsAndDragonsInsiderPlayerCharacterImporter _dungeonsAndDragonsInsiderPlayerCharacterImporter;
        private readonly IOpenFileView _openFileView;
        private readonly ILocationRepository _locationRepository;
        private readonly IMonsterRepository _monsterRepository;
        private readonly IPlayerCharacterRepository _playerCharacterRepository;
        private readonly ICampaignManagerView _view;
        private string _clickedMenuTag;

        public CampaignManagerPresenter(ICampaignManagerView view, IPlayerCharacterRepository playerCharacterRepository,
                                        IMonsterRepository monsterRepository, ILocationRepository locationRepository,
                                        IDungeonsAndDragonsInsiderMonsterImporter dungeonsAndDragonsInsiderMonsterImporter,
                                        IDungeonsAndDragonsInsiderPlayerCharacterImporter dungeonsAndDragonsInsiderPlayerCharacterImporter,
                                        IOpenFileView openFileView)
        {
            _view = view;
            _playerCharacterRepository = playerCharacterRepository;
            _monsterRepository = monsterRepository;
            _locationRepository = locationRepository;
            _dungeonsAndDragonsInsiderMonsterImporter = dungeonsAndDragonsInsiderMonsterImporter;
            _dungeonsAndDragonsInsiderPlayerCharacterImporter = dungeonsAndDragonsInsiderPlayerCharacterImporter;
            _openFileView = openFileView;
        }

        public void CloseSelectedTab()
        {
            string selectedTabName = _view.SelectedTabName;
            if ( !string.IsNullOrEmpty(selectedTabName) )
            {
                _view.RemoveTab(selectedTabName);
                if ( selectedTabName.StartsWith(MONSTER_TAB_PREFIX) )
                {
                    DisplayMonsters();
                }
                if ( selectedTabName.StartsWith(LOCATION_TAB_PREFIX) )
                {
                    DisplayLocations();
                }
            }
            _view.CloseButtonVisible = ( _view.TabCount > 0 );
        }

        public void DisplayCombatTracker()
        {
            _view.AddCombatTrackerTab();
        }

        public void DisplayLocations()
        {
            _view.LocationNames = ( from location in _locationRepository.GetAllNames() orderby location select location ).ToArray();
        }

        public void DisplayMonsters()
        {
            _view.MonsterNames = ( from monster in _monsterRepository.GetAllNames() orderby monster select monster ).ToArray();
        }

        public void DisplayPlayerCharacters()
        {
            _view.PlayerCharacterNames =
                ( from playerCharacter in _playerCharacterRepository.GetAllNames() orderby playerCharacter select playerCharacter ).ToArray();
        }

        public void ProcessMenuItemClick()
        {
            _clickedMenuTag = _view.ClickedMenuItemTag;
            ProcessCombatTrackerClick();
            ProcessNewLocationClick();
            ProcessNewMonsterClick();
            ProcessImportMonsterClick();
            ProcessViewLocationClick();
            ProcessViewMonsterClick();
            ProcessViewPlayerCharacterClick();
            ProcessViewCampaignPlansClick();
            ProcessImportPlayerCharacterClick();
            SetTabCloseButtonVisibility();
        }

        private void ProcessCombatTrackerClick()
        {
            if ( _clickedMenuTag.StartsWith(COMBAT_TRACKER_PREFIX) )
            {
                _view.AddCombatTrackerTab();
            }
        }

        private void ProcessImportMonsterClick()
        {
            if ( !_clickedMenuTag.StartsWith(IMPORT_MONSTER) )
            {
                return;
            }
            string monsterName = _view.MonsterToImport().Trim();
            Monster monster = _dungeonsAndDragonsInsiderMonsterImporter.ImportMonster(123);
            if ( monster != null )
            {
                _monsterRepository.Save(monster);
                DisplayMonsters();
                _view.AddMonsterEditorTab(monster.Name);
            }
            else
            {
                _view.Alert(string.Format("Import failed for '{0}'", monsterName));
            }
        }

        private void ProcessImportPlayerCharacterClick()
        {
            if ( !_clickedMenuTag.StartsWith(IMPORT_PLAYER_CHARACTER) )
            {
                return;
            }
            string filePath = string.Empty;
            using ( OpenFileDialog openFileDialog = new OpenFileDialog
                                                        {
                                                            CheckFileExists = true,
                                                            RestoreDirectory = true,
                                                            Filter = "D&D Insider Character Builder File (*.dnd4e)|*.dnd4e|All files (*.*)|*.*",
                                                            FilterIndex = 1
                                                        } )
            {
                if ( openFileDialog.ShowDialog() == DialogResult.OK )
                {
                    filePath = openFileDialog.FileName;
                }
            }
            PlayerCharacter playerCharacter = _dungeonsAndDragonsInsiderPlayerCharacterImporter.ImportPlayerCharacter(filePath);
            if ( playerCharacter != null )
            {
                _playerCharacterRepository.Save(playerCharacter);
                _view.AddPlayerCharacterEditorTab(playerCharacter.Name);
            }
            else
            {
                _view.Alert(string.Format("Import failed for '{0}'", filePath));
            }
        }

        private void ProcessNewLocationClick()
        {
            if ( _clickedMenuTag.StartsWith(NEW_LOCATION_PREFIX) )
            {
                _view.AddLocationEditorTab(string.Empty);
            }
        }

        private void ProcessNewMonsterClick()
        {
            if ( _clickedMenuTag.StartsWith(NEW_MONSTER_PREFIX) )
            {
                _view.AddMonsterEditorTab(string.Empty);
            }
        }

        private void ProcessViewCampaignPlansClick()
        {
            if ( _clickedMenuTag.StartsWith(CAMPAIGN_PLANS_PREFIX) )
            {
                _view.AddCampaignPlannerTab();
            }
        }

        private void ProcessViewLocationClick()
        {
            if ( _clickedMenuTag.StartsWith(LOCATION_TAB_PREFIX) )
            {
                _view.AddLocationEditorTab(_view.ClickedMenuItemText);
            }
        }

        private void ProcessViewMonsterClick()
        {
            if ( _clickedMenuTag.StartsWith(MONSTER_TAB_PREFIX) )
            {
                _view.AddMonsterEditorTab(_view.ClickedMenuItemText);
            }
        }

        private void ProcessViewPlayerCharacterClick()
        {
            if ( _clickedMenuTag.StartsWith(PLAYER_CHARACTER_TAB_PREFIX) )
            {
                _view.AddPlayerCharacterEditorTab(_view.ClickedMenuItemText);
            }
        }

        private void SetTabCloseButtonVisibility()
        {
            _view.CloseButtonVisible = ( _view.TabCount > 0 );
        }
    }
}